package com.ht.pms.core.controller.excel;

import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ht.pms.core.common.cache.SalaryCodeBuilder;
import com.ht.pms.core.common.cache.SalaryServiceCache;
import com.ht.pms.core.common.constant.SalaryConstants;
import com.ht.pms.core.common.exception.ParamException;
import com.ht.pms.core.config.ExecutorPool;
import com.ht.pms.core.dto.Result;
import com.ht.pms.core.dto.ReturnCodeEnum;
import com.ht.pms.core.dto.poi.ExcelExportQuerySqlReq;
import com.ht.pms.core.dto.poi.SalaryUploadParam;
import com.ht.pms.core.dto.tempalte.Template;
import com.ht.pms.core.dto.upload.UploadFile;
import com.ht.pms.core.dto.upload.UploadFileLog;
import com.ht.pms.core.service.SalaryExcelDataService;
import com.ht.pms.core.service.SalaryTemplateService;
import com.ht.pms.core.service.SalaryUploadFileService;
import com.ht.pms.core.service.job.ThreadManager;

/**
 * excel处理程序
 * 
 * @author yuewen
 *
 */
// @CrossOrigin
@RestController
@RequestMapping("/salaryExcel")
public class SalaryExcelController {
	private static final Logger LOGGER = LoggerFactory.getLogger(SalaryExcelController.class);

	private static final String SALARY_UPLOAD_PROCESS_CODE = "pms:salary:upload:process:";

	@Autowired
	private SalaryExcelDataService salaryExcelDataService;

	@Autowired
	private SalaryUploadFileService salaryUploadFileService;

	@Autowired
	private SalaryTemplateService salaryTemplateService;

	@Autowired
	private SalaryCodeBuilder salaryCodeBuilder;

	@Autowired
	private SalaryServiceCache salaryServiceCache;

	@Autowired
	private ThreadManager threadManager;

	@PostMapping("/uploadSalaryFile")
	public Result upNewSalaryTable(@ModelAttribute SalaryUploadParam req) throws Exception {
		LOGGER.info("[文件上传]文件上传 ，  param:[{}], userId:[{}]", req);
		// 生成内部处理批次号
		Long processCode = salaryCodeBuilder.generateDailyCode(SALARY_UPLOAD_PROCESS_CODE);
		
		if (req.getFile() == null) {
			LOGGER.error("[导入基础数据] 请求参数导入文件为空！");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
					ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": file");
		}
		
		String originalFilename = req.getFile().getOriginalFilename();
		req.setFileName(originalFilename.substring(0, originalFilename.lastIndexOf(".")));
		
		req.setInputStream(req.getFile().getInputStream());
		ExecutorPool.cachedThreadPool.execute(threadManager.createExcelImportThread(req, processCode));
		return Result.buildSuccess(processCode);
	}
	
	@GetMapping("/getUploadSalaryFileState")
	public Result getUploadSalaryFileState(Long processCode, HttpServletRequest request) throws Exception {
		Result result = salaryServiceCache.getUploadProcessResult(processCode);
		if (result == null) {
			result = new Result();
			result.setReturnCode(1);
			result.msg("继续轮询");
		}
		LOGGER.info("[文件上传]轮询获取文件上传结果,  result:[{}]", result);
		return result;
	}

	@PostMapping("/validateUpload")
	public Result validateUpload(@RequestBody SalaryUploadParam req, HttpServletRequest request) throws Exception {
		LOGGER.info("[文件上传]文件上传前校验,  param:[{}]", req);
		return salaryExcelDataService.validateUpload(req);
	}

	/**
	 * 导出
	 * 
	 * @param batchCode
	 * @param type
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/downloadSalaryFile")
	public Result downloadSalaryFile(@ModelAttribute ExcelExportQuerySqlReq reqParam, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		LOGGER.info("[文件上传]文件导出 ，  param:[{}]", reqParam);
		SXSSFWorkbook book = null;
		BufferedOutputStream bufferedOutPut = null;

		if (StringUtils.isEmpty(reqParam.getBatchCode())) {
			return Result.buildFail("没有导出批次！");
		}

		if (StringUtils.isEmpty(reqParam.getTemplateCode())) {
			return Result.buildFail("没有导出模板！");
		}
		Template template = salaryTemplateService.getTemplateByTemplateCode(reqParam.getTemplateCode());

		List<UploadFile> files = salaryUploadFileService.getUploadFileByBatchCode(reqParam.getBatchCode());

		String fileName = "";
		if (files != null) {
			for (UploadFile uploadFile : files) {
				if (uploadFile.getIsDel() == SalaryConstants.SALARY_NO) {
					fileName = uploadFile.getFileName();
					break;
				}
			}
		}
		book = salaryExcelDataService.downloadSalaryFile(reqParam, template);
		if (book == null) {
			return Result.buildFail();
		}
		// 指定下载的文件名
		response.setHeader("Content-Disposition",
				"attachment;filename=" + new String((fileName).getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
		response.setContentType("application/vnd.ms-excel;charset=UTF-8");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		try {
			bufferedOutPut = new BufferedOutputStream(response.getOutputStream());
			bufferedOutPut.flush();
			book.write(bufferedOutPut);
		} finally {
			bufferedOutPut.close();
		}

		return Result.buildSuccess(null);
	}

	/**
	 * 导出错误数据
	 * 
	 * @param fileId
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/exportErrorData")
	public Result exportErrorData(@RequestParam("fileId") Integer fileId, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		LOGGER.info("[文件上传]文件导出 ，  param:[batchCode:{}]", fileId);
		SXSSFWorkbook book = null;
		BufferedOutputStream bufferedOutPut = null;
		UploadFile file = salaryUploadFileService.getUploadFileByFileId(fileId);
		if (file == null) {
			return Result.buildFail();
		}
		book = salaryExcelDataService.exportErrorData(file);
		if (book == null) {
			return Result.buildFail();
		}
		// 指定下载的文件名
		response.setHeader("Content-Disposition",
				"attachment;filename=" + new String(file.getFileName().getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
		response.setContentType("application/vnd.ms-excel;charset=UTF-8");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);

		try {
			bufferedOutPut = new BufferedOutputStream(response.getOutputStream());
			bufferedOutPut.flush();
			book.write(bufferedOutPut);
		} finally {
			bufferedOutPut.close();
		}

		return Result.buildSuccess(null);
	}

	@GetMapping("/getSalaryFileLog")
	public Result getSalaryFileLog(Integer index, Integer fileId, HttpServletRequest request) throws Exception {
		LOGGER.info("[文件上传]获取上传数据处理日志 ，  param:[{}], fileId[{}]", index, fileId);
		List<UploadFileLog> uploadFileLogs = salaryExcelDataService.getSalaryFileLog(index, fileId);

		return Result.buildSuccess(uploadFileLogs);
	}
}
